package com.hzhr.iot.cqgas.ds.service;

import com.hzhr.iot.core.constant.CommonOptions;
import com.hzhr.iot.core.util.HzhrDateUtil;
import com.hzhr.iot.core.util.HzhrTypeUtil;
import com.hzhr.iot.cqgas.ds.dao.device.custom.DevCollectDataCustomDao;
import com.hzhr.iot.cqgas.ds.dao.device.custom.DeviceDao;
import com.hzhr.iot.cqgas.ds.dao.device.example.DevCollectDataDao;
import com.hzhr.iot.cqgas.ds.dao.device.example.DevCollectDeviceDao;
import com.hzhr.iot.cqgas.ds.dao.device.example.DevIotDeviceDao;
import com.hzhr.iot.cqgas.ds.dao.smartmeter.custom.SmCollectDataCustomDao;
import com.hzhr.iot.cqgas.ds.entity.device.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.Future;

@Service
public class CollectingDataService {
    @Autowired
    SmCollectDataCustomDao smCollectDataCustomDao;
    @Autowired
    DevCollectDeviceDao devCollectDeviceDao;
    @Autowired
    DevIotDeviceDao devIotDeviceDao;
    @Autowired
    DevCollectDataDao devCollectDataDao;
    @Autowired
    DevOptionsService devOptionsService;
    @Autowired
    DevCollectDataCustomDao devCollectDataCustomDao;
    @Autowired
    DeviceDao deviceDao;

    private Logger logger = LoggerFactory.getLogger(CollectingDataService.class);

    @Async
    public Future<Integer> syncCollectingData(int ti, Date startDate, Date endDate,
                                              Map<String, Integer> collectDevices,
                                              Map<String, Integer> iotDevices) {
        int syncCount = 0;

        int length = 5000;
        int threadCount = 10;

        String open = devOptionsService.getCode("VALVE_STATUS", "OPEN");
        String close = devOptionsService.getCode("VALVE_STATUS", "CLOSE");
        String error = devOptionsService.getCode("VALVE_STATUS", "ERROR");

        for (int i = ti - 1; ;i += threadCount) {
            try {
                Map<String, Object> criteriaMap = new HashMap<>();
                criteriaMap.put("startRow", i * length + 1);
                criteriaMap.put("endRow", i * length + length);
                if (startDate != null) criteriaMap.put("startDate", HzhrDateUtil.dateToStr(startDate));
                if (endDate != null) criteriaMap.put("endDate", HzhrDateUtil.dateToStr(endDate));
                List<Map<String, Object>> collecingDatas = smCollectDataCustomDao.selectCollectData(criteriaMap);

                //去重
                List<Map<String, Object>> addedList = new ArrayList<>();
                List<Map<String, Object>> collecingDatas1 = new ArrayList<>();
                for (Map<String, Object> collecingData:
                        collecingDatas) {
                    boolean addFlag = true;

                    String eqId = HzhrTypeUtil.object2string(collecingData.get("EQ_ID"));
                    if (eqId == null) continue;
                    String cdTime = HzhrTypeUtil.object2string(collecingData.get("CD_TIME"));
                    if (cdTime == null) continue;

                    for (Map<String, Object> addedItem :
                            addedList) {
                        String eqId1 = HzhrTypeUtil.object2string(addedItem.get("EQ_ID"));
                        String cdTime1 = HzhrTypeUtil.object2string(addedItem.get("CD_TIME"));

                        if (eqId.equals(eqId1) && cdTime.equals(cdTime1)) {
                            addFlag = false;
                            break;
                        }
                    }

                    if (addFlag) {
                        collecingDatas1.add(collecingData);
                        Map<String, Object> addedItem = new HashMap<>();
                        addedItem.put("EQ_ID", eqId);
                        addedItem.put("CD_TIME", cdTime);
                        addedList.add(addedItem);
                    }
                }

                List<DevCollectDataEntity> addList = new ArrayList<>();
                for (Map<String, Object> collectingData :
                        collecingDatas1) {
                    String cdId = HzhrTypeUtil.object2string(collectingData.get("CD_ID"));
                    String nodeId = HzhrTypeUtil.object2string(collectingData.get("NODE_ID"));
                    if (nodeId == null) continue;
                    String eqId = HzhrTypeUtil.object2string(collectingData.get("EQ_ID"));
                    if (eqId == null) continue;
                    String connectionPointNode = HzhrTypeUtil.object2string(collectingData.get("CONNECTION_POINT_NODE"));
                    String cdTime = HzhrTypeUtil.object2string(collectingData.get("CD_TIME"));
                    if (cdTime == null) continue;
                    cdTime = cdTime.substring(0, cdTime.indexOf("."));
                    Date currentTime = HzhrDateUtil.strToDate(cdTime);
                    String currentValue = HzhrTypeUtil.object2string(collectingData.get("CURRENT_VALUE"));
                    if (currentValue == null) continue;
                    String signal = HzhrTypeUtil.object2string(collectingData.get("SIGNAL"));
                    String powertype = HzhrTypeUtil.object2string(collectingData.get("POWERTYPE"));
                    String voltage = HzhrTypeUtil.object2string(collectingData.get("VOLTAGE"));
                    String tmp = HzhrTypeUtil.object2string(collectingData.get("TMP"));
                    String pressure = HzhrTypeUtil.object2string(collectingData.get("PRESSURE"));
                    String temperature = HzhrTypeUtil.object2string(collectingData.get("TEMPERATURE"));
                    String standardFlow = HzhrTypeUtil.object2string(collectingData.get("STANDARD_FLOW"));
                    String workFlow = HzhrTypeUtil.object2string(collectingData.get("WORKING_FLOW"));
                    String standardFlowSum = HzhrTypeUtil.object2string(collectingData.get("STANDARD_FLOW_SUM"));
                    String workFlowSum = HzhrTypeUtil.object2string(collectingData.get("WORKING_FLOW_SUM"));
                    String standardCorrect = HzhrTypeUtil.object2string(collectingData.get("STANDARD_CORRECT"));
                    String valveStateId = HzhrTypeUtil.object2string(collectingData.get("VALVE_STATE_ID"));

                    Integer iotDeviceId = null;
                    if (connectionPointNode != null) {
                        iotDeviceId = iotDevices.get(connectionPointNode);
                    } else {
                        iotDeviceId = iotDevices.get(nodeId);
                    }
                    if (iotDeviceId == null) continue;

                    Integer collectDeviceId = collectDevices.get(eqId);
                    if (collectDeviceId == null) continue;

                    DevCollectDataExample devCollectDataExample = new DevCollectDataExample();
                    devCollectDataExample.createCriteria().andCollectDeviceIdEqualTo(collectDeviceId).andCurrentTmEqualTo(currentTime);
                    int count = devCollectDataDao.countByExample(devCollectDataExample);

                    if (count == 0) {
                        DevCollectDataEntity devCollectDataEntity = new DevCollectDataEntity();
                        devCollectDataEntity.setTemperature(HzhrTypeUtil.string2float(temperature));
                        devCollectDataEntity.setCollectDeviceId(collectDeviceId);
                        devCollectDataEntity.setIotDeviceId(iotDeviceId);
                        devCollectDataEntity.setCurrentTm(currentTime);
                        devCollectDataEntity.setCurrentValue(Double.parseDouble(currentValue));
                        devCollectDataEntity.setStaTotalFlow(HzhrTypeUtil.string2double(standardFlowSum));
                        devCollectDataEntity.setWorkTotalFlow(HzhrTypeUtil.string2double(workFlowSum));
                        devCollectDataEntity.setDisTotalFlow(HzhrTypeUtil.string2double(standardCorrect));
                        devCollectDataEntity.setStaFlowRate(HzhrTypeUtil.string2double(standardFlow));
                        devCollectDataEntity.setWorkFlowRate(HzhrTypeUtil.string2double(workFlow));
                        devCollectDataEntity.setPressure(HzhrTypeUtil.string2double(pressure));
                        devCollectDataEntity.setTemperature(HzhrTypeUtil.string2float(tmp));
                        if ("1".equals(valveStateId)) {
                            devCollectDataEntity.setValveStatusCode(open);
                        } else if ("0".equals(valveStateId)){
                            devCollectDataEntity.setValveStatusCode(close);
                        }
                        devCollectDataEntity.setSignalStrength(HzhrTypeUtil.string2integer(signal));
                        devCollectDataEntity.setCellVoltage(HzhrTypeUtil.string2float(voltage));
                        devCollectDataEntity.setCreateTime(new Date());
                        devCollectDataEntity.setIsValid(CommonOptions.YES_NO.YES);
                        devCollectDataEntity.setState("1");
                        addList.add(devCollectDataEntity);
                    }
                }

                int addListSize = addList.size();
                if (addListSize > 0) {
                    syncCount += addListSize;
                    devCollectDataCustomDao.insertBatch(addList);
                }

                if (collecingDatas.size() < length) break;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        Future<Integer> future = new AsyncResult<Integer>(syncCount);// Future接收返回值，这里是String类型，可以指明其他类型
        return future;
    }

    @Async
    public Future<Integer> syncCollectingData1(Date startDate, Date endDate) {
        int syncCount = 0;


        String open = devOptionsService.getCode("VALVE_STATUS", "OPEN");
        String close = devOptionsService.getCode("VALVE_STATUS", "CLOSE");
        String error = devOptionsService.getCode("VALVE_STATUS", "ERROR");

        try {
            Map<String, Object> criteriaMap = new HashMap<>();
            if (startDate != null) criteriaMap.put("startDate", HzhrDateUtil.dateToStr(startDate));
            if (endDate != null) criteriaMap.put("endDate", HzhrDateUtil.dateToStr(endDate));
            List<Map<String, Object>> collecingDatas = smCollectDataCustomDao.selectCollectData2(criteriaMap);

            //去重
            List<Map<String, Object>> addedList = new ArrayList<>();
            List<Map<String, Object>> collecingDatas1 = new ArrayList<>();
            for (Map<String, Object> collecingData:
            collecingDatas) {
                boolean addFlag = true;

                String eqId = HzhrTypeUtil.object2string(collecingData.get("EQ_ID"));
                if (eqId == null) continue;
                String cdTime = HzhrTypeUtil.object2string(collecingData.get("CD_TIME"));
                if (cdTime == null) continue;

                for (Map<String, Object> addedItem :
                        addedList) {
                    String eqId1 = HzhrTypeUtil.object2string(addedItem.get("EQ_ID"));
                    String cdTime1 = HzhrTypeUtil.object2string(addedItem.get("CD_TIME"));

                    if (eqId.equals(eqId1) && cdTime.equals(cdTime1)) {
                        addFlag = false;
                        break;
                    }
                }

                if (addFlag) {
                    collecingDatas1.add(collecingData);
                    Map<String, Object> addedItem = new HashMap<>();
                    addedItem.put("EQ_ID", eqId);
                    addedItem.put("CD_TIME", cdTime);
                    addedList.add(addedItem);
                }
            }

            List<DevCollectDataEntity> addList = new ArrayList<>();
            for (Map<String, Object> collectingData :
                    collecingDatas1) {
                String cdId = HzhrTypeUtil.object2string(collectingData.get("CD_ID"));
                String nodeId = HzhrTypeUtil.object2string(collectingData.get("NODE_ID"));
                if (nodeId == null) continue;
                String eqId = HzhrTypeUtil.object2string(collectingData.get("EQ_ID"));
                if (eqId == null) continue;
                String connectionPointNode = HzhrTypeUtil.object2string(collectingData.get("CONNECTION_POINT_NODE"));
                String cdTime = HzhrTypeUtil.object2string(collectingData.get("CD_TIME"));
                if (cdTime == null) continue;
                cdTime = cdTime.substring(0, cdTime.indexOf("."));
                Date currentTime = HzhrDateUtil.strToDate(cdTime);
                String currentValue = HzhrTypeUtil.object2string(collectingData.get("CURRENT_VALUE"));
                if (currentValue == null) continue;
                String signal = HzhrTypeUtil.object2string(collectingData.get("SIGNAL"));
                String powertype = HzhrTypeUtil.object2string(collectingData.get("POWERTYPE"));
                String voltage = HzhrTypeUtil.object2string(collectingData.get("VOLTAGE"));
                String tmp = HzhrTypeUtil.object2string(collectingData.get("TMP"));
                String pressure = HzhrTypeUtil.object2string(collectingData.get("PRESSURE"));
                String temperature = HzhrTypeUtil.object2string(collectingData.get("TEMPERATURE"));
                String standardFlow = HzhrTypeUtil.object2string(collectingData.get("STANDARD_FLOW"));
                String workFlow = HzhrTypeUtil.object2string(collectingData.get("WORKING_FLOW"));
                String standardFlowSum = HzhrTypeUtil.object2string(collectingData.get("STANDARD_FLOW_SUM"));
                String workFlowSum = HzhrTypeUtil.object2string(collectingData.get("WORKING_FLOW_SUM"));
                String standardCorrect = HzhrTypeUtil.object2string(collectingData.get("STANDARD_CORRECT"));
                String valveStateId = HzhrTypeUtil.object2string(collectingData.get("VALVE_STATE_ID"));

                Integer iotDeviceId = null;
                if (connectionPointNode != null) {
                    iotDeviceId = deviceDao.select9(connectionPointNode);
                } else {
                    iotDeviceId = deviceDao.select9(nodeId);
                }
                if (iotDeviceId == null) continue;

                Integer collectDeviceId = deviceDao.select8(eqId);
                if (collectDeviceId == null) continue;

                DevCollectDataExample devCollectDataExample = new DevCollectDataExample();
                devCollectDataExample.createCriteria().andCollectDeviceIdEqualTo(collectDeviceId).andCurrentTmEqualTo(currentTime);
                int count = devCollectDataDao.countByExample(devCollectDataExample);

                if (count == 0) {
                    DevCollectDataEntity devCollectDataEntity = new DevCollectDataEntity();
                    devCollectDataEntity.setTemperature(HzhrTypeUtil.string2float(temperature));
                    devCollectDataEntity.setCollectDeviceId(collectDeviceId);
                    devCollectDataEntity.setIotDeviceId(iotDeviceId);
                    devCollectDataEntity.setCurrentTm(currentTime);
                    devCollectDataEntity.setCurrentValue(Double.parseDouble(currentValue));
                    devCollectDataEntity.setStaTotalFlow(HzhrTypeUtil.string2double(standardFlowSum));
                    devCollectDataEntity.setWorkTotalFlow(HzhrTypeUtil.string2double(workFlowSum));
                    devCollectDataEntity.setDisTotalFlow(HzhrTypeUtil.string2double(standardCorrect));
                    devCollectDataEntity.setStaFlowRate(HzhrTypeUtil.string2double(standardFlow));
                    devCollectDataEntity.setWorkFlowRate(HzhrTypeUtil.string2double(workFlow));
                    devCollectDataEntity.setPressure(HzhrTypeUtil.string2double(pressure));
                    devCollectDataEntity.setTemperature(HzhrTypeUtil.string2float(tmp));
                    if ("1".equals(valveStateId)) {
                        devCollectDataEntity.setValveStatusCode(open);
                    } else if ("0".equals(valveStateId)){
                        devCollectDataEntity.setValveStatusCode(close);
                    }
                    devCollectDataEntity.setSignalStrength(HzhrTypeUtil.string2integer(signal));
                    devCollectDataEntity.setCellVoltage(HzhrTypeUtil.string2float(voltage));
                    devCollectDataEntity.setCreateTime(new Date());
                    devCollectDataEntity.setIsValid(CommonOptions.YES_NO.YES);
                    devCollectDataEntity.setState("1");
                    addList.add(devCollectDataEntity);
                }
            }

            int addListSize = addList.size();
            if (addListSize > 0) {
                syncCount += addListSize;
                devCollectDataCustomDao.insertBatch(addList);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        Future<Integer> future = new AsyncResult<Integer>(syncCount);// Future接收返回值，这里是String类型，可以指明其他类型
        return future;
    }
}
